﻿using System.Net.NetworkInformation;

namespace HelperLibrary;

public static class Util
{
    /// <summary>
    /// 批量处理任务工具方法
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="tList"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="action"></param>
    public static void BatchProcess<T>(List<T> tList, int pageSize, Action<List<T>> action)
    {
        if (tList == null || !tList.Any())
        {
            return;
        }

        int pageIndex = 1;
        List<T> tempList = tList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
        while (tempList.Any())
        {
            action.Invoke(tempList);
            pageIndex += 1;
            tempList = tList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
        }
    }

    /// <summary>
    /// 加密
    /// </summary>
    /// <param name="toCryString"></param>
    /// <returns></returns>
    public static string MD5Encrypt(string toCryString)
    {
        var hashmd5 = MD5.Create();
        return BitConverter.ToString(hashmd5.ComputeHash(Encoding.Default.GetBytes(toCryString))).Replace("-", "").ToUpper();
    }

    /// <summary>
    /// 16位的MD5加密
    /// </summary>
    /// <param name="password"></param>
    /// <returns></returns>
    public static string MD5Encrypt16(string password)
    {
        var md5 = MD5.Create();
        string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8);
        t2 = t2.Replace("-", "");
        return t2;
    }

    /// <summary>
    /// 32位MD5加密
    /// </summary>
    /// <param name="password"></param>
    /// <returns></returns>
    public static string MD5Encrypt32(string password)
    {
        string cl = password;
        string pwd = "";
        MD5 md5 = MD5.Create(); //实例化一个md5对像
                                // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
        byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
        // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
        for (int i = 0; i < s.Length; i++)
        {
            // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 
            pwd = pwd + s[i].ToString("X");
        }
        return pwd;
    }

    /// <summary>
    /// 64位的MD5加密
    /// </summary>
    /// <param name="password"></param>
    /// <returns></returns>
    public static string MD5Encrypt64(string password)
    {
        string cl = password;
        //string pwd = "";
        MD5 md5 = MD5.Create(); //实例化一个md5对像
                                // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
        byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl));
        return Convert.ToBase64String(s);
    }

    /// <summary>
    /// 将int数值转换为占四个字节的byte数组，本方法适用于(低位在前，高位在后)的顺序。 和bytesToInt（）配套使用
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static byte[] IntToBytes(int value)
    {
        byte[] src = new byte[4];
        src[3] = (byte)((value >> 24) & 0xFF);
        src[2] = (byte)((value >> 16) & 0xFF);
        src[1] = (byte)((value >> 8) & 0xFF);
        src[0] = (byte)(value & 0xFF);
        return src;
    }

    /// <summary>
    /// 将int数值转换为占四个字节的byte数组，本方法适用于(高位在前，低位在后)的顺序。  和bytesToInt2（）配套使用 
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static byte[] IntToBytes2(int value)
    {
        byte[] src = new byte[4];
        src[0] = (byte)((value >> 24) & 0xFF);
        src[1] = (byte)((value >> 16) & 0xFF);
        src[2] = (byte)((value >> 8) & 0xFF);
        src[3] = (byte)(value & 0xFF);
        return src;
    }

    /// <summary>
    /// byte数组中取int数值，本方法适用于(低位在前，高位在后)的顺序，和和intToBytes（）配套使用 
    /// </summary>
    /// <param name="src">byte数组</param>
    /// <param name="offset">从数组的第offset位开始</param>
    /// <returns></returns>
    public static int BytesToInt(byte[] src, int offset)
    {
        int value;
        value = (int)((src[offset] & 0xFF)
                | ((src[offset + 1] & 0xFF) << 8)
                | ((src[offset + 2] & 0xFF) << 16)
                | ((src[offset + 3] & 0xFF) << 24));
        return value;
    }

    /// <summary>
    /// byte数组中取int数值，本方法适用于(低位在后，高位在前)的顺序。和intToBytes2（）配套使用
    /// </summary>
    /// <param name="src"></param>
    /// <param name="offset"></param>
    /// <returns></returns>
    public static int BytesToInt2(byte[] src, int offset)
    {
        int value;
        value = (int)(((src[offset] & 0xFF) << 24)
                | ((src[offset + 1] & 0xFF) << 16)
                | ((src[offset + 2] & 0xFF) << 8)
                | (src[offset + 3] & 0xFF));
        return value;
    }

    /// <summary>
    /// 生成GUID
    /// </summary>
    /// <param name="type">类型</param>
    /// <returns></returns>
    public static string CreateGUID(int type = 1)
    {
        var uuid = "";
        switch (type)
        {
            case 0:
                uuid = Guid.NewGuid().ToString(); // 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
                break;
            case 1:
                uuid = Guid.NewGuid().ToString("N"); // e0a953c3ee6040eaa9fae2b667060e09
                break;
            case 2:
                uuid = Guid.NewGuid().ToString("D"); // 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
                break;
            case 3:
                uuid = Guid.NewGuid().ToString("B"); // {734fd453-a4f8-4c5d-9c98-3fe2d7079760}
                break;
            case 4:
                uuid = Guid.NewGuid().ToString("P"); // (ade24d16-db0f-40af-8794-1e08e2040df3)
                break;
            case 5:
                uuid = Guid.NewGuid().ToString("X"); // {0x3fa412e3,0x8356,0x428f,{0xaa,0x34,0xb7,0x40,0xda,0xaf,0x45,0x6f}}
                break;
        }
        return uuid;
    }

    /// <summary>
    /// 获取枚举类型的描述
    /// </summary>
    /// <param name="enumeration"></param>
    /// <returns></returns>
    public static string ToDescription(this Enum enumeration)
    {
        Type type = enumeration.GetType();
        MemberInfo[] memInfo = type.GetMember(enumeration.ToString());
        if (null != memInfo && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (null != attrs && attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }
        return enumeration.ToString();
    }

    /// <summary>
    /// 获取枚举类型的描述(二级)
    /// </summary>
    /// <param name="enumeration"></param>
    /// <returns></returns>
    public static string ToDescription2(this Enum enumeration)
    {
        Type type = enumeration.GetType();
        MemberInfo[] memInfo = type.GetMember(enumeration.ToString());
        if (null != memInfo && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description2Attribute), false);
            if (null != attrs && attrs.Length > 0)
                return ((Description2Attribute)attrs[0]).Description;
        }
        return enumeration.ToString();
    }
    /// <summary>  
    /// 判断两个日期是否在同一周  
    /// </summary>  
    /// <param name="dtmS">开始日期</param>  
    /// <param name="dtmE">结束日期</param> 
    /// <returns></returns>  
    public static bool IsInSameWeek(DateTime dtmS, DateTime dtmE)
    {
        TimeSpan ts = dtmE - dtmS;
        double dbl = ts.TotalDays;
        int intDow = Convert.ToInt32(dtmE.DayOfWeek);
        if (intDow == 0) intDow = 7;
        if (dbl >= 7 || dbl >= intDow) return false;
        else return true;
    }

    /// <summary>
    /// 获取地址
    /// </summary>
    /// <param name="addr"></param>
    /// <param name="nginxStr"></param>
    /// <returns></returns>
    public static string GetAddress(string addr, string nginxStr, bool isHttps)
    {
        if (string.IsNullOrWhiteSpace(nginxStr))
        {
            return addr;
        }
        string address = string.Empty;
        if (!string.IsNullOrWhiteSpace(addr))
        {
            string[] strs = addr.Split("://");
            string head = addr.Substring(0, addr.IndexOf(":"));
            var httpstr = isHttps ? "https" : "http";
            address = $"{httpstr}://{nginxStr}/{head}_proxy/{strs[1]}";
        }
        return address;
    }
    /// <summary>
    /// 获取地址
    /// </summary>
    /// <param name="addr"></param>
    /// <param name="nginxStr"></param>
    /// <returns></returns>
    public static string GetAddress(string addr, string nginxStr)
    {
        if (string.IsNullOrWhiteSpace(nginxStr))
        {
            return addr;
        }
        string address = string.Empty;
        if (!string.IsNullOrWhiteSpace(addr))
        {
            string[] strs = addr.Split("://");
            string head = addr.Substring(0, addr.IndexOf(":"));
            if (strs[0] == "http")
            {
                strs[0] = "https";
            }
            address = $"{strs[0]}://{nginxStr}/{head}_proxy/{strs[1]}";
        }
        return address;
    }
    /// <summary>
    /// 获取时间戳
    /// </summary>
    /// <returns></returns>
    public static string GetTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToInt64(ts.TotalSeconds).ToString();
    }
    /// <summary>
    /// MD532位小写
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string MD532(string str)
    {
        var md5Hasher = MD5.Create();
        byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(str));
        StringBuilder sBuilder = new StringBuilder();
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));//转化为小写的16进制
        }
        return sBuilder.ToString();
    }
    /// <summary>
    /// HmacSHA256加密
    /// </summary>
    /// <param name="secret"></param>
    /// <param name="signKey"></param>
    /// <returns></returns>
    public static string HmacSHA256(string secret, string signKey)
    {
        string signRet = string.Empty;
        using (HMACSHA256 mac = new HMACSHA256(Encoding.UTF8.GetBytes(signKey)))
        {
            byte[] hash = mac.ComputeHash(Encoding.UTF8.GetBytes(secret));
            signRet = Convert.ToBase64String(hash);
            //signRet = ToHexString(hash); ;
        }
        return signRet;
    }

    /// <summary>
    /// URL编码
    /// </summary>
    /// <param name="temp"></param>
    /// <returns></returns>
    public static string UrlEncodeStr(string temp)
    {
        StringBuilder builder = new StringBuilder();
        foreach (char c in temp)
        {
            if (HttpUtility.UrlEncode(c.ToString()).Length > 1)
            {
                builder.Append(HttpUtility.UrlEncode(c.ToString()).ToUpper());
            }
            else
            {
                builder.Append(c);
            }
        }
        //Encoding encoding = Encoding.UTF8;
        //string str = HttpUtility.UrlEncode(temp, encoding);
        return builder.ToString();
    }
    public static string GetWeek(DateTime datetime)
    {
        string week = string.Empty;
        switch ((int)datetime.DayOfWeek)
        {
            case 0:
                week = "星期日";
                break;
            case 1:
                week = "星期一";
                break;
            case 2:
                week = "星期二";
                break;
            case 3:
                week = "星期三";
                break;
            case 4:
                week = "星期四";
                break;
            case 5:
                week = "星期五";
                break;
            default:
                week = "星期六";
                break;
        }
        return week;
    }

    public static Dictionary<string, string> GetCurrentWeek(DateTime datetime)
    {
        Dictionary<string, string> dic = new Dictionary<string, string>();
        DateTime startweek = datetime.AddDays(1 - Convert.ToInt32(datetime.DayOfWeek.ToString("d"))); //获取一周的开始日期
        DateTime endweek = startweek.AddDays(6); //获取本周星期天日期
        for (int i = 0; i < 7; i++)
        {
            DateTime otherweek = startweek.AddDays(i);
            string strdata = otherweek.ToString("yyyy-MM-dd");
            string strweek = GetWeek(otherweek);
            dic.Add(strdata, strweek);
        }
        return dic;
    }

    /// <summary>  
    /// 截取字符串 
    /// </summary>   
    public static string Substring(string sub)
    {
        if (!string.IsNullOrEmpty(sub))
        {
            int index = sub.IndexOf(",");
            if (index > 0)
            {
                sub = sub.Substring(0, index);
            }
        }
        return sub;
    }

    /// <summary>
    /// 判断当前时间是否在开始时间和结束时间范围内
    /// </summary>
    /// <param name="stime">开始时间</param>
    /// <param name="etime">结束时间</param>
    /// <param name="aheadTime">提前时间</param>
    /// <param name="delayTime">延后时间</param>
    /// <returns></returns>        
    public static int IsInBetweenTime(string stime, string etime, string? aheadTime = null, string? delayTime = null)
    {
        string todayStr = DateTime.Now.ToString("yyyy-MM-dd");
        if (!string.IsNullOrEmpty(aheadTime))
        {
            stime = Convert.ToDateTime($"{todayStr} {stime}")
                .AddMinutes(-Convert.ToInt32(aheadTime)).ToString("HH:mm");
        }
        if (!string.IsNullOrEmpty(delayTime))
        {
            etime = Convert.ToDateTime($"{todayStr} {etime}")
                .AddMinutes(Convert.ToInt32(delayTime)).ToString("HH:mm");
        }
        int result = 0;
        string nowtime = DateTime.Now.ToString("HH:mm");
        int start = string.Compare(nowtime, stime, true);
        int end = string.Compare(nowtime, etime, true);
        if ((start == 0 || start == 1) && (end == -1 || end == 0))
        {
            result = 1;
        }
        else
        {
            result = 2;
        }
        return result;
    }

    /// <summary>
    /// 合并数组
    /// </summary>
    /// <param name="First">第一个数组</param>
    /// <param name="Second">第二个数组</param>
    /// <returns>合并后的数组(第一个数组+第二个数组，长度为两个数组的长度)</returns>
    public static string[] MergerArray(string[] First, string[] Second)
    {
        string[] result = new string[First.Length + Second.Length];
        First.CopyTo(result, 0);
        Second.CopyTo(result, First.Length);
        return result;
    }

    /// <summary>
    /// 数组追加
    /// </summary>
    /// <param name="Source">原数组</param>
    /// <param name="str">字符串</param>
    /// <returns>合并后的数组(数组+字符串)</returns>
    public static string[] AppendArray(string[] Source, string str)
    {
        string[] result = new string[Source.Length + 1];
        Source.CopyTo(result, 0);
        result[Source.Length] = str;
        return result;
    }

    public static string CreateAVCCode()
    {
        return "AVC" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
    }

    /// <summary>
    /// 创建文件夹
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    public static bool CreateFolder(string path)
    {
        string[] arr = path.Split('\\');
        List<string> list = new List<string>();
        foreach (string str in arr)
            list.Add(str);
        string folder = "";
        while (list.Count > 0)
        {
            folder += list[0] + "\\";
            if (Directory.Exists(folder) == false)
            {
                Directory.CreateDirectory(folder);
                while (true)
                {
                    if (Directory.Exists(folder))
                        break;
                    Thread.CurrentThread.Join(300);
                }
            }
            list.RemoveAt(0);
        }
        return true;
    }

    /// <summary>
    /// 过滤字段
    /// </summary>
    /// <param name="obj"></param>
    /// <param name="fields"></param>
    /// <returns></returns>
    public static JObject FilterFieldFromObject(object obj, string fields)
    {
        JObject result = new JObject();
        string[] fieldArr = fields.Split(",");
        foreach (PropertyInfo p in obj.GetType().GetProperties())
        {
            string key = p.Name;
            if (fieldArr.Contains(key))
            {
                if (p.GetValue(obj) == null)
                {
                    result.Add(ConvertFirstLetterToLower(key), null);
                }
                else
                {
                    result.Add(ConvertFirstLetterToLower(key), JToken.FromObject(p.GetValue(obj)));
                }
            }
        }
        return result;
    }

    /// <summary>
    /// 过滤字段
    /// </summary>
    /// <param name="objs"></param>
    /// <param name="fields"></param>
    /// <returns></returns>
    public static JArray FilterFieldFromList<T>(List<T> objs, string fields)
    {
        JArray result = new JArray();
        foreach (object obj in objs)
        {
            result.Add(FilterFieldFromObject(obj, fields));
        }
        return result;
    }

    /// <summary>
    /// 获取In 条件 ('item1', 'item2', 'item3')
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public static string GetInCondition(List<int> ids)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("(");
        for (int i = 0; i < ids.Count; i++)
        {
            sb.Append(ids[i]);
            if (i != ids.Count - 1)
            {
                sb.Append(",");
            }
        }
        sb.Append(")");

        return sb.ToString();
    }

    /// <summary>
    /// 获取In 条件 ('item1', 'item2', 'item3')
    /// </summary>
    /// <param name="strList"></param>
    /// <returns></returns>
    public static string GetInCondition(List<string> strList)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("(");
        for (int i = 0; i < strList.Count; i++)
        {
            sb.Append("'");
            sb.Append(strList[i]);
            sb.Append("'");
            if (i != strList.Count - 1)
            {
                sb.Append(",");
            }
        }
        sb.Append(")");

        return sb.ToString();
    }

    public static readonly string EncryptSalt = "_avc_";

    

    

    /// <summary>
    /// 电话号码隐藏
    /// </summary>
    /// <param name="telephoneSource"></param>
    /// <returns></returns>
    public static string PhoneHide(string telephoneSource)
    {
        string telephone = string.Empty;
        if (!string.IsNullOrEmpty(telephoneSource)
            && telephoneSource.Contains(Util.EncryptSalt))
        {
            string partStart = telephoneSource.Substring(0, 3);
            string partEnd = telephoneSource.Substring(telephoneSource.Length - 4, 4);
            telephone = $"{partStart}****{partEnd}";
        }
        return telephone;
    }

    /// <summary>
    /// 判断列表是否为空
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list"></param>
    /// <returns></returns>
    public static bool ListIsNullOrEmpty<T>(List<T> list)
    {
        if (list == null || list.Count == 0)
        {
            return true;
        }
        return false;
    }

    /// <summary>
    /// 获取学期周
    /// </summary>
    /// <param name="termBeginDate"></param>
    /// <param name="date"></param>
    /// <returns></returns>
    public static int GetSemesterWeekNum(DateTime termBeginDate, DateTime date)
    {
        DateTime termBeginDateWeekFirstDay = DateTimeHelper.GetWeekDay(termBeginDate, 1);
        DateTime dateWeekFirstDay = DateTimeHelper.GetWeekDay(date, 1);
        int diffDay = (int)DateTimeHelper.DateDiff(termBeginDateWeekFirstDay, dateWeekFirstDay, TimeType.Day);
        return diffDay / 7 + 1;
    }

    /// <summary>
    /// 删除文件
    /// </summary>
    /// <param name="fileDirect"></param>
    /// <param name="saveDay"></param>
    public static void DeleteFile(List<string> fileDirects, int saveDay)
    {
        DateTime nowTime = DateTime.Now;
        foreach (string fileDirect in fileDirects)
        {
            if (!Directory.Exists(fileDirect))
            {
                continue;
            }
            string[] files = Directory.GetFiles(fileDirect, "*.log", SearchOption.AllDirectories);  //获取该目录下所有 .txt文件
            foreach (string file in files)
            {
                FileInfo fileInfo = new FileInfo(file);
                TimeSpan t = nowTime - fileInfo.CreationTime;  //当前时间  减去 文件创建时间
                int day = t.Days;
                if (day > saveDay)   //保存的时间 ；  单位：天
                {
                    File.Delete(file);  //删除超过时间的文件
                }
            }
        }
    }

    /// <summary>
    /// 删除文件
    /// </summary>
    /// <param name="dir"></param>
    public static void DeleteFile(string dir)
    {
        if (Directory.Exists(dir))
        {
            var files = Directory.GetFiles(dir);
            if (files.Length > 0)
            {
                foreach (var file in files)
                {
                    if (System.IO.File.Exists(file))
                    {
                        System.IO.File.Delete(file);
                    }
                }
            }
        }
    }
    /// <summary>
    /// 导入设备Excel参数验证
    /// </summary>
    /// <param name="row"></param>
    /// <param name="deviceTypeParamNameList"></param>
    /// <param name="deviceTypeName"></param>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public static string ImportDeviceExcelParamVerify(string row, List<string> deviceTypeParamNameList, string deviceTypeName)
    {
        // 扩展参数检查

        if (string.IsNullOrWhiteSpace(row)) return null;
        if (row.Contains("：") || row.Contains("，"))
        {
            return "扩展参数不能使用中文全角冒号或逗号";
        }

        if (!row.Contains(":") || !row.Contains(","))
        {
            return "扩展参数必须包含冒号或逗号";
        }

        if (row.Contains(","))
        {
            var strList = row.Split(",");

            foreach (var str in strList)
            {
                if (!str.Contains(":"))
                {
                    return "扩展参数必须包含冒号";
                }

                var param = str.Split(":");
                string key;
                string value;
                try
                {
                    key = param[0];
                    value = param[1];
                }
                catch
                {
                    return "扩展参数必须包含参数名、参数值";
                }

                if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value))
                {
                    return "扩展参数参数名、参数值不可为空";
                }

                if (!deviceTypeParamNameList.Contains(key))
                {
                    return $"{deviceTypeName}设备扩展参数不包含参数名{key}，请检查资产类型参数配置";
                }
            }
        }
        else
        {
            if (!row.Contains(":"))
            {
                return "扩展参数必须包含冒号";
            }

            var param = row.Split(":");
            string key;
            string value;
            try
            {
                key = param[0];
                value = param[1];
            }
            catch
            {
                return "扩展参数必须包含参数名、参数值";
            }

            if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value))
            {
                return "扩展参数参数名、参数值不可为空";
            }

            if (!deviceTypeParamNameList.Contains(key))
            {
                return $"{deviceTypeName}设备扩展参数不包含参数名{key}，请检查资产类型参数配置";
            }
        }
        return null;
    }

    public static bool IsMac(string mac)
    {
        Regex r1 = new Regex("^([A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}$");
        Regex r2 = new Regex("^([A-Fa-f0-9]{2}-){7}[A-Fa-f0-9]{2}$");
        Regex r3 = new Regex("^([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}$");
        Regex r4 = new Regex("^([A-Fa-f0-9]{2}:){7}[A-Fa-f0-9]{2}$");
        var r1Flag = r1.IsMatch(mac);
        var r2Flag = r2.IsMatch(mac);
        var r3Flag = r3.IsMatch(mac);
        var r4Flag = r4.IsMatch(mac);
        if (!r1Flag && !r2Flag && !r3Flag && !r4Flag)
        {
            return false;
        }
        return true;
    }

    public static string ConvertFirstLetterToLower(string input)
    {
        // 检查输入字符串是否为空或只包含空格
        if (string.IsNullOrWhiteSpace(input))
        {
            return input;
        }

        // 获取第一个字符，并将其转换为小写
        char firstChar = char.ToLower(input[0]);

        // 创建一个新的字符串，除了第一个字符外，其他字符与原始字符串相同
        string result = firstChar + input.Substring(1);

        return result;
    }
    public static bool IsValidIp(string ipAddress)
    {
        var IpPattern = new Regex(@"^(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})$");
        return IpPattern.IsMatch(ipAddress);
    }

    /// <summary>
    /// 根据Ip获取定位
    /// </summary>
    /// <param name="strIp"></param>
    /// <returns></returns>
    public static string GetstringIpAddress(string strIp)
    {
        try
        {
            if (strIp == "127.0.0.1")
            {
                return "校内";
            }
            string html = GetHtml("https://www.ip138.com/iplookup.asp?ip=" + strIp + "&action=2", "gb2312");
            string pre = "var ip_result = {\"ASN归属地\":\"";
            int pos = html.IndexOf(pre);
            html = html.Substring(pos + pre.Length);
            html = html.Substring(0, html.IndexOf('"'));
            string[] res = html.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (res.Any(x => x.Contains("北京市")) || res.Any(x => x.Contains("上海市")) || res.Any(x => x.Contains("天津市")) || res.Any(x => x.Contains("重庆市")))
            {
                return res[0].Substring(0, 3);
            }
            if (!res[0].Contains("市") && !res[0].Contains("洲") && !res[0].Contains("地区") && !res[0].Contains("盟"))
            {
                return "校内";
            }
            Log.Write($"strIp:{strIp},addr:{res[0]}");
            return res[0];
        }
        catch (Exception)
        {
            return string.Empty;
        }
    }

    /// <summary>
    /// 抓取网页查询信息
    /// </summary>
    /// <param name="url"></param>
    /// <param name="encoding">编码类型</param>
    /// <returns></returns>
    public static string GetHtml(string url, string encoding)
    {
        string pagehtml = string.Empty;
        try
        {
            using (WebClient MyWebClient = new WebClient())
            {
                //控制台应用和.net core 需要这一句，需要安装NetGet包System.Text.Encoding.CodePages
                Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
                Encoding encode = Encoding.GetEncoding(encoding);
                MyWebClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36");
                MyWebClient.Credentials = CredentialCache.DefaultCredentials;
                Byte[] pageData = MyWebClient.DownloadData(url);
                pagehtml = encode.GetString(pageData);
            }
        }
        catch (Exception ex)
        {

            return "访问" + url + "失败，请检查网络配置";
        }
        return pagehtml;
    }

    /// <summary>
    /// 获取小时分钟
    /// </summary>
    /// <param name="temp"></param>
    /// <returns></returns>
    public static string GetHourMins(DateTime date)
    {
        string h = string.Empty;
        string m = string.Empty;
        if (date.Hour < 10)
        {
            h = "0";
        }
        if (date.Minute < 10)
        {
            m = "0";
        }

        return h + date.Hour.ToString() + ":" + m + date.Minute.ToString();
    }
    /// <summary>
    /// 替换字符串中的中文
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static string ReplaceChinese(string input) 
    {
        if (string.IsNullOrWhiteSpace(input))
        {
            return "";
        }
        string pattern = "[\u4e00-\u9fa5]";
        return Regex.Replace(input, pattern, "");
    }
    /// <summary>
    /// 计算综合评定
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcOverallGrade(string overalGrade)
    {
        var gradeStr = "";
        if (overalGrade == "A")
        {
            gradeStr = "优秀";
        }
        else if (overalGrade == "B")
        {
            gradeStr = "良好";
        }
        else if (overalGrade == "C")
        {
            gradeStr = "一般";
        }
        else if (overalGrade == "D")
        {
            gradeStr = "较差";
        }
        return gradeStr;
    }
    /// <summary>
    /// 计算综合评定
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcOverallGrade(double score,out string gradeStr)
    {
        var grade = "";
        gradeStr = "";
        if (score > 83 && score <= 100)
        {
            grade = "A";
            gradeStr = "优秀";
        }
        else if (score > 70 && score <= 83)
        {
            grade = "B";
            gradeStr = "良好";
        }
        else if (score > 50 && score <= 70)
        {
            grade = "C";
            gradeStr = "一般";
        }
        else if (score > 0 && score <= 50)
        {
            grade = "D";
            gradeStr = "较差";
        }
        return grade;
    }

    /// <summary>
    /// 计算负面情绪等级(综合项)
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcNegativeGrade(double score)
    {
        var grade = "";
        if (score > 0 && score <= 25)
        {
            grade = "无";
        }
        else if (score > 25 && score <= 50)
        {
            grade = "较低";
        }
        else if (score > 50 && score <= 75)
        {
            grade = "偏高";
        }
        else if (score > 75 && score <= 100)
        {
            grade = "较高";
        }
        return grade;
    }

    /// <summary>
    /// 计算负面情绪等级(心理情绪分析)
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcNegativeDetailGrade(double score)
    {
        var grade = "";
        if (score > 0 && score <= 25)
        {
            grade = "较低";
        }
        else if (score > 25 && score <= 50)
        {
            grade = "轻度";
        }
        else if (score > 50 && score <= 75)
        {
            grade = "中度";
        }
        else if (score > 75 && score <= 100)
        {
            grade = "重度";
        }
        return grade;
    }

    /// <summary>
    /// 计算负面情绪等级(心理情绪分析)
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcNegativeGrade2(int score)
    {
        var grade = "";
        if (score == 1)
        {
            grade = "较低";
        }
        else if (score == 2)
        {
            grade = "轻度";
        }
        else if (score == 3)
        {
            grade = "中度";
        }
        else if (score == 4)
        {
            grade = "重度";
        }
        return grade;
    }
    /// <summary>
    /// 计算正面情绪等级(心理情绪分析)
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcPositiveGrade2(int score)
    {
        var grade = "";
        if (score == 1)
        {
            grade = "充足";
        }
        else if (score == 2)
        {
            grade = "偏低";
        }
        else if (score == 3)
        {
            grade = "较低";
        }
        else if (score == 4)
        {
            grade = "过低";
        }
        return grade;
    }
    /// <summary>
    /// 计算正面情绪等级(综合项)
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcPositiveGrade(double score)
    {
        var grade = "";
        if (score > 75 && score <= 100)
        {
            grade = "充足";
        }
        else if (score > 50 && score <= 75)
        {
            grade = "较高";
        }
        else if (score > 25 && score <= 50)
        {
            grade = "较低";
        }
        else if (score > 0 && score <= 25)
        {
            grade = "过低";
        }
        return grade;
    }

    /// <summary>
    /// 计算心理能力等级
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcMentalabilityGrade(double score)
    {
        var grade = "";
        if (score > 75 && score <= 100)
        {
            grade = "优秀";
        }
        else if (score > 50 && score <= 75)
        {
            grade = "良好";
        }
        else if (score > 25 && score <= 50)
        {
            grade = "一般";
        }
        else if (score > 0 && score <= 25)
        {
            grade = "较差";
        }
        return grade;
    }
    /// <summary>
    /// 计算心理能力等级
    /// </summary>
    /// <param name="score"></param>
    /// <returns></returns>
    public static string CalcMentalabilityGrade2(int score)
    {
        var grade = "";
        if (score == 1)
        {
            grade = "优秀";
        }
        else if (score == 2)
        {
            grade = "良好";
        }
        else if (score == 3)
        {
            grade = "一般";
        }
        else if (score == 4)
        {
            grade = "较差";
        }
        return grade;
    }
    /// <summary>
    /// 获取百分比
    /// </summary>
    /// <param name="param1">参数1</param>
    /// <param name="param2">参数2</param>
    /// <param name="digits">小数位数</param>
    /// <returns></returns>
    public static double GetRate(int param1, int param2, int digits = 2)
    {
        if (param2 == 0)
        {
            return 0;
        }
        if (param1 > param2)
        {
            return 100;
        }
        else
        {
            //抬头率： 抬头人数/实到人数*100%
            return param2 > 0 ? Math.Round(Convert.ToDouble(param1 * 100.00 / param2), digits) : 0;
        }
    }
    /// <summary>
    /// 电话号码加密
    /// </summary>
    /// <param name="phoneNum"></param>
    /// <returns></returns>
    public static string PhoneEncrypt(string phoneNum)
    {
        if (string.IsNullOrEmpty(phoneNum)
            || phoneNum.Length != 11
            || phoneNum.Contains(EncryptSalt))
        {
            return phoneNum;
        }

        string partStart = phoneNum.Substring(0, 3);
        string partCenter = phoneNum.Substring(3, 4);
        string partEnd = phoneNum.Substring(7, 4);
        return $"{partStart}{EncryptSalt}{DESEncrypt.EncryptDes(partCenter, $"{partStart}{partEnd}&")}{partEnd}";
    }

    /// <summary>
    /// 电话号码解密
    /// </summary>
    /// <param name="encryptedPhoneNum"></param>
    /// <returns></returns>
    public static string PhoneDecrypt(string encryptedPhoneNum)
    {
        if (string.IsNullOrEmpty(encryptedPhoneNum)
            || !encryptedPhoneNum.Contains(EncryptSalt))
        {
            return encryptedPhoneNum;
        }

        string partStart = encryptedPhoneNum.Substring(0, 3);
        string partCenter = encryptedPhoneNum.Substring(3, encryptedPhoneNum.Length - 7);
        partCenter = partCenter.Replace(EncryptSalt, string.Empty);
        string partEnd = encryptedPhoneNum.Substring(encryptedPhoneNum.Length - 4, 4);
        return $"{partStart}{DESEncrypt.DecryptDes(partCenter, $"{partStart}{partEnd}&")}{partEnd}";
    }

    // 将字节数组保存为图片文件的方法
    public static void SaveImageFromBytes(byte[] imageBytes, string filePath)
    {
        using (FileStream fs = new FileStream(filePath, FileMode.Create))
        {
            fs.Write(imageBytes, 0, imageBytes.Length);
        }
    }
    /// <summary>
    /// pingIp地址
    /// </summary>
    /// <param name="ip"></param>
    /// <returns></returns>
    public static int PingIp(string ip) 
    {
        var status = 0;
        Ping pingSender = new Ping();
        PingReply reply = pingSender.Send(ip, 120);
        if (reply.Status == IPStatus.Success)
        {
            status = 1;
        }
        else
        {
            reply = pingSender.Send(ip, 120);
            status = reply.Status == IPStatus.Success ? 1 : 0;
        }
        return status;
    }
}
